<template>
    <el-dialog
        fullscreen
        title="代码预览"
        v-model="visible"
        width="90%"
        top="3vh"
        append-to-body
        :close-on-click-modal="false"
    >
        <splitpanes>
            <pane size="25">
                <el-scrollbar height="calc(100vh - 100px)" class="mt20">
                    <el-tree
                        ref="treeRef"
                        node-key="id"
                        :data="preview.fileTree"
                        :expand-on-click-node="false"
                        highlight-current
                        @node-click="handleNodeClick"
                    />
                </el-scrollbar>
            </pane>
            <pane>
                <el-tabs v-model="preview.activeName" @tab-click="handleTabClick">
                    <el-tab-pane
                        v-for="item in previewCodegen"
                        :label="item.codePath.substring(item.codePath.lastIndexOf('/') + 1)"
                        :name="item.codePath"
                        :key="item.codePath"
                    >
                        <SvgIcon name="ele-CopyDocument" :size="25" class="copy_btn" @click="copyText(item.code)" />
                    </el-tab-pane>
                    <code-editor
                        ref="codeEditorRef"
                        theme="darcula"
                        v-model="previewCodeStr"
                        mode="go"
                        readOnly
                        height="calc(100vh - 100px)"
                    ></code-editor>
                </el-tabs>
            </pane>
        </splitpanes>
    </el-dialog>
</template>
<script setup lang="ts" name="preview">
    import { useGeneratorPreviewApi } from '@/api/gen/table'
    import { handleTree } from '@/utils/other'
    import commonFunction from '@/utils/commonFunction'
    const CodeEditor = defineAsyncComponent(() => import('@/components/CodeEditor/index.vue'))

    const { copyText } = commonFunction()

    const visible = ref(false)
    // ======== 显示页面 ========
    const preview = reactive({
        open: false,
        titel: '代码预览',
        fileTree: [],
        activeName: ''
    })

    const previewCodegen = ref([])
    const previewCodeStr = ref('')
    const fileTreeOriginal = ref([] as any[])

    const openDialog = async (id: string) => {
        await getGenCodeFile(id)
        visible.value = true
    }

    const loading = ref(false)
    const codeEditorRef = ref()

    /**
     * 获取特定资源的代码生成文件，显示在页面上。
     * @param id 需要渲染的资源 ID。
     */
    const getGenCodeFile = (id: string) => {
        loading.value = true
        fileTreeOriginal.value = []
        useGeneratorPreviewApi(id)
            .then((res: any) => {
                previewCodegen.value = res
                for (let index in res) {
                    fileTreeOriginal.value.push(res[index].codePath)
                }
                // 默认选中第一个 选项卡
                previewCodeStr.value = res[0].code
                preview.activeName = res[0].codePath
                const files = handleFiles(fileTreeOriginal)
                preview.fileTree = handleTree(files, 'id', 'parentId', 'children', '/')
            })
            .finally(() => {
                loading.value = false
            })
    }

    const handleNodeClick = async (data: any, node: any) => {
        if (node && !node.isLeaf) {
            return false
        }

        preview.activeName = data.id

        const filteredCode = previewCodegen.value.filter((code: any) => code.codePath === data.id)
        if (filteredCode.length > 0) {
            previewCodeStr.value = filteredCode[0].code
        }
    }

    const handleTabClick = (item: any) => {
        const filteredCode = previewCodegen.value.filter((code: any) => code.codePath === item.paneName)
        if (filteredCode.length > 0) {
            previewCodeStr.value = filteredCode[0].code
        }
    }

    /**
     * 生成 files 目录
     * @param fileTreeOriginal
     * @returns {*[]}
     */
    const handleFiles = (fileTreeOriginal: any) => {
        const exists = {}
        const files = [] as any[]

        // 遍历每个元素
        for (const data of fileTreeOriginal.value) {
            let paths = []
            if (data.includes('\\')) {
                paths = data.split('\\')
            } else {
                paths = data.split('/')
            }
            let fullPath = '' // 从头开始的路径，用于生成 id
            // 遍历每个 path， 拼接成树
            for (let i = 0; i < paths.length; i++) {
                // 已经添加到 files 中，则跳过
                const oldFullPath = fullPath
                // 下面的 replaceAll 的原因，是因为上面包处理了，导致和 tabs 不匹配，所以 replaceAll 下
                fullPath = fullPath.length === 0 ? paths[i] : fullPath.replaceAll('.', '/') + '/' + paths[i]
                if (exists[fullPath]) {
                    continue
                }
                // 添加到 files 中
                exists[fullPath] = true
                files.push({
                    id: fullPath,
                    label: paths[i],
                    parentId: oldFullPath || '/',
                    templateName: data.k
                })
            }
        }
        return files
    }

    defineExpose({
        openDialog
    })
</script>

<style scoped lang="scss">
    .copy_btn {
        position: absolute;
        top: 10px;
        right: 20px;
        z-index: 9;
        color: white;
    }
</style>
